﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SVN.Net.Models
{
    public partial class SVN
    {
        private const string CST_MESSAGE = "Remotely commited by SVN.Net.";

        private string GetMessage(string message)
        {
            return string.IsNullOrEmpty(message) ? CST_MESSAGE : message;
        }

        public ProcessXmlResult List(string url, string uid, string pwd)
        {
            return XmlExecute(string.Format("list \"{0}\"", url), uid, pwd);
        }

        public ProcessResult CheckOut(string path, string uid, string pwd, ref string localPath)
        {
            localPath = System.IO.Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/workingdir"), Guid.NewGuid().ToString());
            System.IO.Directory.CreateDirectory(localPath);
            return NormalExecute(string.Format("checkout \"{0}\" \"{1}\" --depth files", path, localPath), uid, pwd);
        }

        public ProcessResult CommitSingleFile(string path, string message, string uid, string pwd)
        {
            return NormalExecute(string.Format("commit \"{0}\" --message \"{1}\"", path, GetMessage(message)), uid, pwd);
        }

        public ProcessResult Move(string src, string dest, string message, string uid, string pwd)
        {
            return NormalExecute(string.Format("move \"{0}\" \"{1}\" --message \"{2}\"", src, dest, GetMessage(message)), uid, pwd);
        }

        public ProcessResult Delete(string repo, string uid, string pwd)
        {
            return NormalExecute(string.Format("delete \"{0}\" --message \"{1}\"", repo, CST_MESSAGE), uid, pwd);
        }

        public ProcessResult MakeDir(string repo, string message, string uid, string pwd)
        {
            return NormalExecute(string.Format("mkdir \"{0}\" --message \"{1}\"", repo, GetMessage(message)), uid, pwd);
        }

        public ProcessResult Add(string localPath, string uid, string pwd)
        {
            return NormalExecute(string.Format("add \"{0}\"", localPath), uid, pwd);
        }

        public ProcessResult Cat(string repo, string uid, string pwd)
        {
            return NormalExecute(string.Format("cat \"{0}\"", repo), uid, pwd);
        }

        public bool Exist(string repo, string uid, string pwd)
        {
            bool ret = false;
            var path = GlobalApplication.GetPath(repo);
            var name = GlobalApplication.GetName(repo);
            var lst = List(path, uid, pwd);
            if (lst.Success)
                foreach (System.Xml.XmlNode node in lst.XmlResult.SelectNodes("lists/list//entry/name"))
                    if (string.Compare(name, node.InnerText, true) == 0)
                    {
                        ret = true;
                        break;
                    }
            return ret;
        }

        public byte[] Export(string repo, string uid, string pwd, ref string localPath)
        {
            // Export the directory tree from SVN server.
            localPath = System.IO.Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/workingdir"), Guid.NewGuid().ToString());
            var r = NormalExecute(string.Format("export \"{0}\" \"{1}\"", repo, localPath), uid, pwd);
            if (r.Success)
            {
                // Zip it into a memory stream.
                var zip = new ICSharpCode.SharpZipLib.Zip.FastZip();
                var ms = new System.IO.MemoryStream();
                zip.CreateZip(ms, localPath, true, string.Empty, string.Empty);
                // Return the byte array for this zip file.
                return ms.ToArray();
            }
            else
                return null;
        }
    }
}
